using SqlsugarService.Application.DTOs.PlanDto;
using SqlsugarService.Application.Until;
using SqlsugarService.Domain.BOM;
using SqlsugarService.Domain.Materials;
using SqlsugarService.Domain.Plan;
using SqlsugarService.Infrastructure.IRepository;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using SqlsugarService.Application.IService.Plan;

namespace SqlsugarService.Application.Service.Plan
{
    /// <summary>
    /// BOM分解服务
    /// 负责将生产计划的BOM树形分解成多个生产工单
    /// </summary>
    public class BomDecompositionService : IBomDecompositionService
    {
        private readonly IBaseRepository<ProductionPlan> _productionPlanRepository;
        private readonly IBaseRepository<ProductionOrder> _productionOrderRepository;
        private readonly IBaseRepository<BomItem> _bomItemRepository;
        private readonly IBaseRepository<BomInfo> _bomInfoRepository;
        private readonly ISqlSugarClient _db;
        private readonly IProductionPlanService _productionPlanService;

        public BomDecompositionService(
            IBaseRepository<ProductionPlan> productionPlanRepository,
            IBaseRepository<ProductionOrder> productionOrderRepository,
            IBaseRepository<BomItem> bomItemRepository,
            IBaseRepository<BomInfo> bomInfoRepository,
            ISqlSugarClient db,
            IProductionPlanService productionPlanService)
        {
            _productionPlanRepository = productionPlanRepository;
            _productionOrderRepository = productionOrderRepository;
            _bomItemRepository = bomItemRepository;
            _bomInfoRepository = bomInfoRepository;
            _db = db;
            _productionPlanService = productionPlanService;
        }

        /// <summary>
        /// 分解生产计划为生产工单
        /// </summary>
        /// <param name="productionPlanId">生产计划ID</param>
        /// <returns>分解结果</returns>
        public async Task<ApiResult<BomDecompositionResult>> DecomposeProductionPlan(Guid productionPlanId)
        {
            try
            {
                // 1. 验证生产计划状态
                var validationResult = await ValidateProductionPlanForDecomposition(productionPlanId);
                if (!validationResult.IsValid)
                {
                    return ApiResult<BomDecompositionResult>.Fail(validationResult.ErrorMessage, ResultCode.Error);
                }

                var productionPlan = validationResult.ProductionPlan;

                // 2. 通过BomId获取BOM树形结构（使用新的GetBomTreeStructure方法）
                var bomTreeResult = await _productionPlanService.GetBomTreeStructure(productionPlan.BomId);
                if (!bomTreeResult.IsSuc || bomTreeResult.Data == null || !bomTreeResult.Data.Any())
                {
                    return ApiResult<BomDecompositionResult>.Fail("BOM结构为空，无法分解", ResultCode.Error);
                }

                // 3. 分析BOM树形结构，识别需要生成工单的产品
                var decompositionItems = AnalyzeBomTreeStructureForDecomposition(bomTreeResult.Data, productionPlan.PlanQuantity);

                // 4. 生成生产工单
                var productionOrders = await GenerateProductionOrdersFromBomTreeStructure(decompositionItems, productionPlan);

                // 5. 计算工单时间安排
                var scheduledOrders = CalculateWorkOrderSchedule(productionOrders, productionPlan);

                // 6. 保存生产工单
                var savedOrders = await SaveProductionOrders(scheduledOrders);

                // 7. 更新生产计划状态为已分解
                await UpdateProductionPlanStatus(productionPlanId, 1); // 1 = 已分解

                var result = new BomDecompositionResult
                {
                    ProductionPlanId = productionPlanId,
                    TotalOrders = savedOrders.Count,
                    Orders = savedOrders,
                    DecompositionItems = decompositionItems,
                    DecompositionTime = DateTime.Now
                };

                return ApiResult<BomDecompositionResult>.Success(result, ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult<BomDecompositionResult>.Fail($"分解失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 撤销已分解的工单
        /// </summary>
        /// <param name="productionPlanId">生产计划ID</param>
        /// <returns>撤销结果</returns>
        public async Task<ApiResult<BomDecompositionResult>> UndoDecomposition(Guid productionPlanId)
        {
            try
            {
                // 1. 验证生产计划状态
                var validationResult = await ValidateProductionPlanForUndo(productionPlanId);
                if (!validationResult.IsValid)
                {
                    return ApiResult<BomDecompositionResult>.Fail(validationResult.ErrorMessage, ResultCode.Error);
                }

                var productionPlan = validationResult.ProductionPlan;

                // 2. 查询相关的生产工单（只查询未删除的）
                var relatedOrders = await _productionOrderRepository.AsQueryable()
                    .Where(po => po.ProductionPlanId == productionPlanId && !po.IsDeleted)
                    .ToListAsync();

                if (!relatedOrders.Any())
                {
                    return ApiResult<BomDecompositionResult>.Fail("未找到相关的生产工单", ResultCode.Error);
                }

                // 3. 检查工单状态，只有未开始的工单才能撤销
                var startedOrders = relatedOrders.Where(po => po.Status != "待排产").ToList();
                if (startedOrders.Any())
                {
                    var orderNames = string.Join(", ", startedOrders.Select(o => o.OrderName));
                    return ApiResult<BomDecompositionResult>.Fail($"以下工单已开始，无法撤销：{orderNames}", ResultCode.Error);
                }

                // 4. 软删除生产工单
                var deletedCount = 0;
                foreach (var order in relatedOrders)
                {
                    // 使用软删除方法
                    order.MarkAsDeleted("系统撤销");
                    var updateResult = await _productionOrderRepository.UpdateAsync(order);
                    if (updateResult)
                    {
                        deletedCount++;
                    }
                }

                // 5. 更新生产计划状态为未分解
                await UpdateProductionPlanStatus(productionPlanId, 0); // 0 = 未分解

                var result = new BomDecompositionResult
                {
                    ProductionPlanId = productionPlanId,
                    TotalOrders = deletedCount,
                    Orders = relatedOrders,
                    UndoTime = DateTime.Now
                };

                return ApiResult<BomDecompositionResult>.Success(result, ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult<BomDecompositionResult>.Fail($"撤销失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 预览生产计划分解结果
        /// </summary>
        /// <param name="productionPlanId">生产计划ID</param>
        /// <returns>分解预览结果</returns>
        public async Task<ApiResult<BomDecompositionPreview>> PreviewDecomposition(Guid productionPlanId)
        {
            try
            {
                // 1. 获取生产计划信息（排除已删除的）
                var productionPlan = await _productionPlanRepository.AsQueryable()
                    .Where(pp => pp.Id == productionPlanId && !pp.IsDeleted)
                    .FirstAsync();

                if (productionPlan == null)
                {
                    return ApiResult<BomDecompositionPreview>.Fail("生产计划不存在或已被删除", ResultCode.Error);
                }

                // 2. 通过BomId获取BOM树形结构（使用新的GetBomTreeStructure方法）
                var bomTreeResult = await _productionPlanService.GetBomTreeStructure(productionPlan.BomId);
                if (!bomTreeResult.IsSuc || bomTreeResult.Data == null || !bomTreeResult.Data.Any())
                {
                    return ApiResult<BomDecompositionPreview>.Fail("BOM结构为空", ResultCode.Error);
                }

                // 3. 分析BOM结构
                var decompositionItems = AnalyzeBomTreeStructureForDecomposition(bomTreeResult.Data, productionPlan.PlanQuantity);

                // 4. 生成预览结果
                var preview = new BomDecompositionPreview
                {
                    ProductionPlanId = productionPlanId,
                    ProductionPlanName = productionPlan.PlanName,
                    BomId = productionPlan.BomId,
                    PlanQuantity = productionPlan.PlanQuantity,
                    DecompositionItems = decompositionItems,
                    EstimatedOrders = decompositionItems.Count(d => d.IsProduct && d.MaterialType == MaterialTypeEnum.Product),
                    CanDecompose = productionPlan.Status == 0, // 只有未分解状态才能分解
                    CurrentStatus = GetStatusDescription(productionPlan.Status)
                };

                return ApiResult<BomDecompositionPreview>.Success(preview, ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult<BomDecompositionPreview>.Fail($"预览失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 查询已删除的生产工单
        /// </summary>
        /// <param name="productionPlanId">生产计划ID</param>
        /// <returns>已删除的工单列表</returns>
        public async Task<ApiResult<List<ProductionOrder>>> GetDeletedProductionOrders(Guid productionPlanId)
        {
            try
            {
                // 验证生产计划是否存在
                var productionPlan = await _productionPlanRepository.AsQueryable()
                    .Where(pp => pp.Id == productionPlanId && !pp.IsDeleted)
                    .FirstAsync();

                if (productionPlan == null)
                {
                    return ApiResult<List<ProductionOrder>>.Fail("生产计划不存在或已被删除", ResultCode.Error);
                }

                // 查询已删除的工单
                var deletedOrders = await _productionOrderRepository.AsQueryable()
                    .Where(po => po.ProductionPlanId == productionPlanId && po.IsDeleted)
                    .OrderByDescending(po => po.DeletedAt)
                    .ToListAsync();

                return ApiResult<List<ProductionOrder>>.Success(deletedOrders, ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult<List<ProductionOrder>>.Fail($"查询失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 恢复已删除的生产工单
        /// </summary>
        /// <param name="productionPlanId">生产计划ID</param>
        /// <param name="orderIds">要恢复的工单ID列表</param>
        /// <returns>恢复结果</returns>
        public async Task<ApiResult<BomDecompositionResult>> RestoreDeletedOrders(Guid productionPlanId, List<Guid> orderIds)
        {
            try
            {
                // 1. 验证生产计划状态
                var validationResult = await ValidateProductionPlanForUndo(productionPlanId);
                if (!validationResult.IsValid)
                {
                    return ApiResult<BomDecompositionResult>.Fail(validationResult.ErrorMessage, ResultCode.Error);
                }

                // 2. 查询要恢复的已删除工单
                var ordersToRestore = await _productionOrderRepository.AsQueryable()
                    .Where(po => po.ProductionPlanId == productionPlanId &&
                                po.IsDeleted &&
                                orderIds.Contains(po.Id))
                    .ToListAsync();

                if (!ordersToRestore.Any())
                {
                    return ApiResult<BomDecompositionResult>.Fail("未找到要恢复的工单", ResultCode.Error);
                }

                // 3. 恢复工单（取消软删除标记）
                var restoredCount = 0;
                foreach (var order in ordersToRestore)
                {
                    // 取消软删除标记
                    order.IsDeleted = false;
                    order.DeletedAt = null;
                    order.DeletedBy = null;
                    order.MarkAsUpdated("系统恢复");

                    var updateResult = await _productionOrderRepository.UpdateAsync(order);
                    if (updateResult)
                    {
                        restoredCount++;
                    }
                }

                // 4. 更新生产计划状态为已分解
                await UpdateProductionPlanStatus(productionPlanId, 1); // 1 = 已分解

                var result = new BomDecompositionResult
                {
                    ProductionPlanId = productionPlanId,
                    TotalOrders = restoredCount,
                    Orders = ordersToRestore,
                    DecompositionTime = DateTime.Now
                };

                return ApiResult<BomDecompositionResult>.Success(result, ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult<BomDecompositionResult>.Fail($"恢复失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 永久删除生产工单（硬删除）
        /// </summary>
        /// <param name="productionPlanId">生产计划ID</param>
        /// <param name="orderIds">要永久删除的工单ID列表</param>
        /// <returns>删除结果</returns>
        //public async Task<ApiResult<BomDecompositionResult>> PermanentlyDeleteOrders(Guid productionPlanId, List<Guid> orderIds)
        //{
        //    try
        //    {
        //        // 1. 验证生产计划状态
        //        var validationResult = await ValidateProductionPlanForUndo(productionPlanId);
        //        if (!validationResult.IsValid)
        //        {
        //            return ApiResult<BomDecompositionResult>.Fail(validationResult.ErrorMessage, ResultCode.Error);
        //        }

        //        // 2. 查询要永久删除的已删除工单
        //        var ordersToDelete = await _productionOrderRepository.AsQueryable()
        //            .Where(po => po.ProductionPlanId == productionPlanId && 
        //                        po.IsDeleted && 
        //                        orderIds.Contains(po.Id))
        //            .ToListAsync();

        //        if (!ordersToDelete.Any())
        //        {
        //            return ApiResult<BomDecompositionResult>.Fail("未找到要删除的工单", ResultCode.Error);
        //        }

        //        // 3. 永久删除工单
        //        var deletedCount = 0;
        //        foreach (var order in ordersToDelete)
        //        {
        //            var deleteResult = await _productionOrderRepository.DeleteAsync(order.Id);
        //            if (deleteResult)
        //            {
        //                deletedCount++;
        //            }
        //        }

        //        var result = new BomDecompositionResult
        //        {
        //            ProductionPlanId = productionPlanId,
        //            TotalOrders = deletedCount,
        //            Orders = ordersToDelete,
        //            UndoTime = DateTime.Now
        //        };

        //        return ApiResult<BomDecompositionResult>.Success(result, ResultCode.Success);
        //    }
        //    catch (Exception ex)
        //    {
        //        return ApiResult<BomDecompositionResult>.Fail($"永久删除失败：{ex.Message}", ResultCode.Error);
        //    }
        //}

        /// <summary>
        /// 获取BOM分解详情
        /// </summary>
        /// <param name="productionPlanId">生产计划ID</param>
        /// <returns>分解详情</returns>
        public async Task<ApiResult<BomDecompositionDetail>> GetBomDecompositionDetail(Guid productionPlanId)
        {
            try
            {
                // 1. 获取生产计划信息
                var productionPlan = await _productionPlanRepository.AsQueryable()
                    .Where(pp => pp.Id == productionPlanId && !pp.IsDeleted)
                    .FirstAsync();

                if (productionPlan == null)
                {
                    return ApiResult<BomDecompositionDetail>.Fail("生产计划不存在或已被删除", ResultCode.Error);
                }

                // 2. 通过BomId获取BOM树形结构（使用新的GetBomTreeStructure方法）
                var bomTreeResult = await _productionPlanService.GetBomTreeStructure(productionPlan.BomId);
                if (!bomTreeResult.IsSuc || bomTreeResult.Data == null || !bomTreeResult.Data.Any())
                {
                    return ApiResult<BomDecompositionDetail>.Fail("BOM结构为空", ResultCode.Error);
                }

                // 3. 分析BOM结构
                var decompositionItems = AnalyzeBomTreeStructureForDecomposition(bomTreeResult.Data, productionPlan.PlanQuantity);

                // 4. 获取已生成的工单
                var existingOrders = await _productionOrderRepository.AsQueryable()
                    .Where(po => po.ProductionPlanId == productionPlanId && !po.IsDeleted)
                    .ToListAsync();

                // 5. 构建详细信息
                var detail = new BomDecompositionDetail
                {
                    ProductionPlanId = productionPlanId,
                    ProductionPlanName = productionPlan.PlanName,
                    BomId = productionPlan.BomId,
                    PlanQuantity = productionPlan.PlanQuantity,
                    PlanStartTime = productionPlan.PlanStartTime,
                    PlanEndTime = productionPlan.PlanEndTime,
                    Status = productionPlan.Status,
                    StatusDescription = GetStatusDescription(productionPlan.Status),
                    
                    // BOM结构信息
                    BomTreeNodes = bomTreeResult.Data.Count,
                    TotalDecompositionItems = decompositionItems.Count,
                    
                    // 产品信息
                    ProductItems = decompositionItems.Where(d => d.IsProduct && d.MaterialType == MaterialTypeEnum.Product).ToList(),
                    ProductCount = decompositionItems.Count(d => d.MaterialType == MaterialTypeEnum.Product),
                    
                    // 物料信息
                    MaterialItems = decompositionItems.Where(d => d.MaterialType == MaterialTypeEnum.Material).ToList(),
                    MaterialCount = decompositionItems.Count(d => d.MaterialType == MaterialTypeEnum.Material),
                    
                    // 工单信息
                    WillGenerateOrders = decompositionItems.Count(d => d.IsProduct && d.MaterialType == MaterialTypeEnum.Product),
                    ExistingOrders = existingOrders,
                    ExistingOrderCount = existingOrders.Count,
                    
                    // 分解状态
                    CanDecompose = productionPlan.Status == 0,
                    IsDecomposed = productionPlan.Status == 1,
                    
                    // 时间信息
                    AnalysisTime = DateTime.Now
                };

                return ApiResult<BomDecompositionDetail>.Success(detail, ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult<BomDecompositionDetail>.Fail($"获取分解详情失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 验证生产计划是否可以分解
        /// </summary>
        /// <param name="productionPlanId">生产计划ID</param>
        /// <returns>验证结果</returns>
        private async Task<ValidationResult> ValidateProductionPlanForDecomposition(Guid productionPlanId)
        {
            var productionPlan = await _productionPlanRepository.AsQueryable()
                .Where(pp => pp.Id == productionPlanId && !pp.IsDeleted)
                .FirstAsync();

            if (productionPlan == null)
            {
                return new ValidationResult { IsValid = false, ErrorMessage = "生产计划不存在或已被删除" };
            }

            // 只有未分解状态(0)才能分解
            if (productionPlan.Status != 0)
            {
                var statusDesc = GetStatusDescription(productionPlan.Status);
                return new ValidationResult { IsValid = false, ErrorMessage = $"生产计划状态为{statusDesc}，无法分解" };
            }

            return new ValidationResult { IsValid = true, ProductionPlan = productionPlan };
        }

        /// <summary>
        /// 验证生产计划是否可以撤销
        /// </summary>
        /// <param name="productionPlanId">生产计划ID</param>
        /// <returns>验证结果</returns>
        private async Task<ValidationResult> ValidateProductionPlanForUndo(Guid productionPlanId)
        {
            var productionPlan = await _productionPlanRepository.AsQueryable()
                .Where(pp => pp.Id == productionPlanId && !pp.IsDeleted)
                .FirstAsync();

            if (productionPlan == null)
            {
                return new ValidationResult { IsValid = false, ErrorMessage = "生产计划不存在或已被删除" };
            }

            // 只有已分解状态(1)才能撤销
            if (productionPlan.Status != 1)
            {
                var statusDesc = GetStatusDescription(productionPlan.Status);
                return new ValidationResult { IsValid = false, ErrorMessage = $"生产计划状态为{statusDesc}，无法撤销" };
            }

            return new ValidationResult { IsValid = true, ProductionPlan = productionPlan };
        }

        /// <summary>
        /// 获取状态描述
        /// </summary>
        /// <param name="status">状态码</param>
        /// <returns>状态描述</returns>
        private string GetStatusDescription(int status)
        {
            return status switch
            {
                0 => "未分解",
                1 => "已分解",
                2 => "已完成",
                3 => "已关闭",
                4 => "已撤回",
                5 => "进行中",
                _ => "未知状态"
            };
        }

        /// <summary>
        /// 分析BOM树形结构，识别需要生成工单的产品
        /// </summary>
        /// <param name="bomTree">BOM树形结构</param>
        /// <param name="planQuantity">计划数量</param>
        /// <returns>分解项目列表</returns>
        private List<DecompositionItem> AnalyzeBomTreeForDecomposition(List<BomTreeDto> bomTree, decimal planQuantity)
        {
            var decompositionItems = new List<DecompositionItem>();

            foreach (var node in bomTree)
            {
                AnalyzeBomTreeNodeForDecomposition(node, planQuantity, decompositionItems);
            }

            return decompositionItems;
        }

        /// <summary>
        /// 分析BOM树节点，识别需要生成工单的产品
        /// </summary>
        /// <param name="node">BOM树节点</param>
        /// <param name="parentQuantity">父级数量</param>
        /// <param name="decompositionItems">分解项目列表</param>
        private void AnalyzeBomTreeNodeForDecomposition(BomTreeDto node, decimal parentQuantity, List<DecompositionItem> decompositionItems)
        {
            // 计算当前节点的实际数量
            var actualQuantity = node.UsageQuantity * parentQuantity;

            // 判断是否为产品（根据节点类型和BOM编号判断）
            // 如果节点有BOM编号，说明这是一个产品节点，需要生成生产工单
            var isProduct = !string.IsNullOrEmpty(node.BomNumber) && node.UsageQuantity > 0;

            if (isProduct)
            {
                // 尝试从产品编号获取物料ID
                var materialId = GetMaterialIdFromProductNumber(node.ProductNumber);
                
                var decompositionItem = new DecompositionItem
                {
                    MaterialId = materialId,
                    MaterialName = node.ProductName,
                    MaterialNumber = node.ProductNumber,
                    RequiredQuantity = actualQuantity,
                    Unit = node.Unit,
                    Level = 0, // 可以根据需要设置层级
                    IsProduct = true,
                    ParentNodeId = null,
                    MaterialType = MaterialTypeEnum.Product
                };

                decompositionItems.Add(decompositionItem);
            }

            // 递归分析子节点
            foreach (var child in node.Children)
            {
                AnalyzeBomTreeNodeForDecomposition(child, actualQuantity, decompositionItems);
            }
        }

        /// <summary>
        /// 分析BOM树形结构，识别需要生成工单的产品
        /// </summary>
        /// <param name="bomTree">BOM树形结构</param>
        /// <param name="planQuantity">计划数量</param>
        /// <returns>分解项目列表</returns>
        private List<DecompositionItem> AnalyzeBomTreeStructureForDecomposition(List<BomTreeStructureDto> bomTree, decimal planQuantity)
        {
            var decompositionItems = new List<DecompositionItem>();

            foreach (var node in bomTree)
            {
                AnalyzeBomTreeStructureNodeForDecomposition(node, planQuantity, decompositionItems);
            }

            return decompositionItems;
        }

        /// <summary>
        /// 分析BOM树节点，识别需要生成工单的产品
        /// </summary>
        /// <param name="node">BOM树节点</param>
        /// <param name="parentQuantity">父级数量</param>
        /// <param name="decompositionItems">分解项目列表</param>
        private void AnalyzeBomTreeStructureNodeForDecomposition(BomTreeStructureDto node, decimal parentQuantity, List<DecompositionItem> decompositionItems)
        {
            // 计算当前节点的实际数量
            var actualQuantity = node.UsageQuantity * parentQuantity;

            // 判断是否为产品节点
            // 1. 有BOM编号的节点
            // 2. 或者MaterialType为Product的节点
            // 3. 或者有产品名称的节点
            var isProduct = (!string.IsNullOrEmpty(node.BomNumber) && node.UsageQuantity > 0) ||
                           (node.MaterialType == MaterialTypeEnum.Product) ||
                           (!string.IsNullOrEmpty(node.ProductName) && node.UsageQuantity > 0);

            if (isProduct)
            {
                // 获取产品ID（优先使用MaterialId，其次尝试解析ProductNumber）
                var productId = node.MaterialId != Guid.Empty ? node.MaterialId : GetMaterialIdFromProductNumber(node.ProductNumber);
                
                // 获取产品名称（优先使用ProductName，其次使用MaterialName）
                var productName = !string.IsNullOrEmpty(node.ProductName) ? node.ProductName : node.MaterialName;
                
                // 获取产品编号（优先使用ProductNumber，其次使用MaterialNumber）
                var productNumber = !string.IsNullOrEmpty(node.ProductNumber) ? node.ProductNumber : node.MaterialNumber;
                
                // 获取规格信息（优先使用ProductSpecification，其次使用MaterialSpecification）
                var specification = !string.IsNullOrEmpty(node.ProductSpecification) ? node.ProductSpecification : node.MaterialSpecification;
                
                var decompositionItem = new DecompositionItem
                {
                    MaterialId = productId,
                    MaterialName = productName ?? "未知产品",
                    MaterialNumber = productNumber ?? "未知编号",
                    RequiredQuantity = actualQuantity,
                    Unit = node.Unit ?? "个",
                    Level = node.Level,
                    IsProduct = true,
                    ParentNodeId = node.ParentItemId,
                    MaterialType = MaterialTypeEnum.Product,
                    
                    // 新增产品详细信息
                    ProductSpecification = specification ?? "未知规格",
                    BomNumber = node.BomNumber ?? "未知BOM编号",
                    BomVersion = node.BomVersion ?? "1.0",
                    DisplayName = node.DisplayName ?? productName ?? "未知产品",
                    DisplayProductNumber = node.DisplayProductNumber ?? productNumber ?? "未知编号",
                    DisplaySpecification = node.DisplaySpecification ?? specification ?? "未知规格"
                };

                decompositionItems.Add(decompositionItem);
                
                Console.WriteLine($"识别到产品节点: {productName} (ID: {productId}, 编号: {productNumber}, 数量: {actualQuantity} {node.Unit})");
            }

            // 递归分析子节点
            foreach (var child in node.Children)
            {
                AnalyzeBomTreeStructureNodeForDecomposition(child, actualQuantity, decompositionItems);
            }
        }

        /// <summary>
        /// 根据产品编号获取物料ID
        /// </summary>
        /// <param name="productNumber">产品编号</param>
        /// <returns>物料ID</returns>
        private Guid GetMaterialIdFromProductNumber(string productNumber)
        {
            try
            {
                // 如果产品编号是有效的GUID，直接转换
                if (Guid.TryParse(productNumber, out Guid materialId))
                {
                    return materialId;
                }

                // 否则生成一个新的GUID（临时方案）
                // 在实际应用中，应该根据产品编号查询数据库获取对应的物料ID
                return Guid.NewGuid();
            }
            catch
            {
                return Guid.NewGuid();
            }
        }

        /// <summary>
        /// 从BOM树生成生产工单
        /// </summary>
        /// <param name="decompositionItems">分解项目</param>
        /// <param name="productionPlan">生产计划</param>
        /// <returns>生产工单列表</returns>
        private async Task<List<ProductionOrder>> GenerateProductionOrdersFromBomTree(List<DecompositionItem> decompositionItems, ProductionPlan productionPlan)
        {
            var productionOrders = new List<ProductionOrder>();

            // 验证生产计划信息
            if (productionPlan == null)
            {
                throw new ArgumentNullException(nameof(productionPlan), "生产计划不能为空");
            }

            if (productionPlan.Id == Guid.Empty)
            {
                throw new ArgumentException("生产计划ID不能为空", nameof(productionPlan));
            }

            // 只处理产品类型的分解项目，生成生产工单
            var productItems = decompositionItems.Where(d => d.IsProduct && d.MaterialType == MaterialTypeEnum.Product).ToList();
            
            if (!productItems.Any())
            {
                // 如果没有产品类型的项目，记录日志但不抛出异常
                // 这可能是因为BOM中只包含物料，没有需要生产的产品
                return productionOrders;
            }

            foreach (var item in productItems)
            {
                var orderNumber = GenerateOrderNumber();
                var now = DateTime.UtcNow;

                var productionOrder = new ProductionOrder
                {
                    Id = Guid.NewGuid(),
                    OrderNumber = orderNumber,
                    OrderName = $"{item.MaterialName}生产工单",
                    ProductionPlanId = productionPlan.Id,
                    ProductId = item.MaterialId,
                    ProductName = item.MaterialName ?? "未知产品",
                    ProductNumber = item.MaterialNumber ?? "未知编号",
                    Specification = item.MaterialName ?? "未知规格",
                    Unit = item.Unit ?? "个",
                    PlanQuantity = item.RequiredQuantity,
                    ActualQuantity = 0,
                    PlanStartTime = productionPlan.PlanStartTime,
                    PlanEndTime = productionPlan.PlanEndTime,
                    Status = "待排产",
                    // 设置BaseEntity的字段
                    CreatedAt = now,
                    UpdatedAt = now,
                    CreatedBy = "系统",
                    UpdatedBy = "系统",
                    IsDeleted = false,
                    DeletedAt = null,
                    DeletedBy = null
                };

                // 验证关键字段
                if (productionOrder.ProductionPlanId == Guid.Empty)
                {
                    throw new InvalidOperationException($"生产工单的生产计划ID为空，生产计划ID: {productionPlan.Id}");
                }

                if (string.IsNullOrEmpty(productionOrder.OrderNumber))
                {
                    throw new InvalidOperationException("生产工单编号为空");
                }

                productionOrders.Add(productionOrder);
            }

            return productionOrders;
        }

        /// <summary>
        /// 从BOM树生成生产工单
        /// </summary>
        /// <param name="decompositionItems">分解项目</param>
        /// <param name="productionPlan">生产计划</param>
        /// <returns>生产工单列表</returns>
        private async Task<List<ProductionOrder>> GenerateProductionOrdersFromBomTreeStructure(List<DecompositionItem> decompositionItems, ProductionPlan productionPlan)
        {
            var productionOrders = new List<ProductionOrder>();

            // 验证生产计划信息
            if (productionPlan == null)
            {
                throw new ArgumentNullException(nameof(productionPlan), "生产计划不能为空");
            }

            if (productionPlan.Id == Guid.Empty)
            {
                throw new ArgumentException("生产计划ID不能为空", nameof(productionPlan));
            }

            // 只处理产品类型的分解项目，生成生产工单
            var productItems = decompositionItems.Where(d => d.IsProduct && d.MaterialType == MaterialTypeEnum.Product).ToList();
            
            if (!productItems.Any())
            {
                // 如果没有产品类型的项目，记录日志但不抛出异常
                // 这可能是因为BOM中只包含物料，没有需要生产的产品
                Console.WriteLine("警告：没有找到需要生成工单的产品项目");
                return productionOrders;
            }

            Console.WriteLine($"准备为 {productItems.Count} 个产品生成生产工单");

            foreach (var item in productItems)
            {
                var orderNumber = GenerateOrderNumber();
                var now = DateTime.UtcNow;

                // 使用完整的产品信息创建工单
                var productionOrder = new ProductionOrder
                {
                    Id = Guid.NewGuid(),
                    OrderNumber = orderNumber,
                    OrderName = $"{item.DisplayName}生产工单",
                    ProductionPlanId = productionPlan.Id,
                    ProductId = item.MaterialId,
                    ProductName = item.DisplayName ?? item.MaterialName ?? "未知产品",
                    ProductNumber = item.DisplayProductNumber ?? item.MaterialNumber ?? "未知编号",
                    Specification = item.DisplaySpecification ?? item.ProductSpecification ?? "未知规格",
                    Unit = item.Unit ?? "个",
                    PlanQuantity = item.RequiredQuantity,
                    ActualQuantity = 0,
                    PlanStartTime = productionPlan.PlanStartTime,
                    PlanEndTime = productionPlan.PlanEndTime,
                    Status = "待排产",
                    // 设置BaseEntity的字段
                    CreatedAt = now,
                    UpdatedAt = now,
                    CreatedBy = "系统",
                    UpdatedBy = "系统",
                    IsDeleted = false,
                    DeletedAt = null,
                    DeletedBy = null
                };

                // 验证关键字段
                if (productionOrder.ProductionPlanId == Guid.Empty)
                {
                    throw new InvalidOperationException($"生产工单的生产计划ID为空，生产计划ID: {productionPlan.Id}");
                }

                if (string.IsNullOrEmpty(productionOrder.OrderNumber))
                {
                    throw new InvalidOperationException("生产工单编号为空");
                }

                Console.WriteLine($"生成工单: {productionOrder.OrderName} (编号: {productionOrder.OrderNumber}, 产品: {productionOrder.ProductName}, 数量: {productionOrder.PlanQuantity} {productionOrder.Unit})");

                productionOrders.Add(productionOrder);
            }

            Console.WriteLine($"成功生成 {productionOrders.Count} 个生产工单");
            return productionOrders;
        }

        /// <summary>
        /// 计算工单时间安排
        /// </summary>
        /// <param name="productionOrders">生产工单列表</param>
        /// <param name="productionPlan">生产计划</param>
        /// <returns>安排后的工单列表</returns>
        private List<ProductionOrder> CalculateWorkOrderSchedule(List<ProductionOrder> productionOrders, ProductionPlan productionPlan)
        {
            if (!productionOrders.Any())
                return productionOrders;

            // 按层级和数量排序，确保子工单在父工单之前完成
            // 层级越低（Level越小）的工单优先级越高
            var sortedOrders = productionOrders.OrderBy(o => o.PlanQuantity).ThenBy(o => o.ProductName).ToList();

            var totalDuration = productionPlan.PlanEndTime - productionPlan.PlanStartTime;
            var orderCount = sortedOrders.Count;
            
            // 如果只有一个工单，使用全部时间
            if (orderCount == 1)
            {
                var order = sortedOrders[0];
                order.PlanStartTime = productionPlan.PlanStartTime;
                order.PlanEndTime = productionPlan.PlanEndTime;
                order.ActualStartTime = productionPlan.PlanStartTime;
                order.ActualEndTime = productionPlan.PlanEndTime;
                return sortedOrders;
            }

            // 多个工单时，按比例分配时间
            var durationPerOrder = totalDuration.TotalHours / orderCount;
            var currentTime = productionPlan.PlanStartTime;

            foreach (var order in sortedOrders)
            {
                order.PlanStartTime = currentTime;
                order.PlanEndTime = currentTime.AddHours((double)durationPerOrder);
                order.ActualStartTime = currentTime;
                order.ActualEndTime = currentTime.AddHours((double)durationPerOrder);
                currentTime = order.PlanEndTime;
            }

            return sortedOrders;
        }

        /// <summary>
        /// 保存生产工单
        /// </summary>
        /// <param name="productionOrders">生产工单列表</param>
        /// <returns>保存的工单列表</returns>
        private async Task<List<ProductionOrder>> SaveProductionOrders(List<ProductionOrder> productionOrders)
        {
            var savedOrders = new List<ProductionOrder>();

            if (!productionOrders.Any())
            {
                return savedOrders;
            }

            foreach (var order in productionOrders)
            {
                try
                {
                    // 再次验证关键字段
                    if (order.ProductionPlanId == Guid.Empty)
                    {
                        throw new InvalidOperationException($"生产工单的生产计划ID为空，工单编号: {order.OrderNumber}");
                    }

                    if (string.IsNullOrEmpty(order.OrderNumber))
                    {
                        throw new InvalidOperationException("生产工单编号为空");
                    }

                    // 尝试保存
                    var result = await _productionOrderRepository.InsertAsync(order);
                    if (result)
                    {
                        savedOrders.Add(order);
                    }
                    else
                    {
                        throw new InvalidOperationException($"保存生产工单失败，工单编号: {order.OrderNumber}");
                    }
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException($"保存生产工单时发生错误，工单编号: {order.OrderNumber}, 错误: {ex.Message}", ex);
                }
            }

            return savedOrders;
        }

        /// <summary>
        /// 更新生产计划状态
        /// </summary>
        /// <param name="productionPlanId">生产计划ID</param>
        /// <param name="status">新状态</param>
        private async Task UpdateProductionPlanStatus(Guid productionPlanId, int status)
        {
            var productionPlan = await _productionPlanRepository.AsQueryable()
                .Where(pp => pp.Id == productionPlanId && !pp.IsDeleted)
                .FirstAsync();

            if (productionPlan != null)
            {
                productionPlan.Status = status;
                productionPlan.MarkAsUpdated("系统更新");
                await _productionPlanRepository.UpdateAsync(productionPlan);
            }
        }

        /// <summary>
        /// 生成工单编号
        /// </summary>
        /// <returns>工单编号</returns>
        private string GenerateOrderNumber()
        {
            var now = DateTime.Now;
            var timePart = now.ToString("yyyyMMddHHmmssfff");
            return $"SCGD{timePart}";
        }
    }

    /// <summary>
    /// 分解项目
    /// </summary>
    public class DecompositionItem
    {
        public Guid MaterialId { get; set; }
        public string MaterialName { get; set; }
        public string MaterialNumber { get; set; }
        public decimal RequiredQuantity { get; set; }
        public string Unit { get; set; }
        public int Level { get; set; }
        public bool IsProduct { get; set; }
        public string ParentNodeId { get; set; }
        public MaterialTypeEnum MaterialType { get; set; }
        
        // 新增产品详细信息字段
        public string ProductSpecification { get; set; }
        public string BomNumber { get; set; }
        public string BomVersion { get; set; }
        public string DisplayName { get; set; }
        public string DisplayProductNumber { get; set; }
        public string DisplaySpecification { get; set; }
    }

    /// <summary>
    /// BOM分解结果
    /// </summary>
    public class BomDecompositionResult
    {
        public Guid ProductionPlanId { get; set; }
        public int TotalOrders { get; set; }
        public List<ProductionOrder> Orders { get; set; }
        public List<DecompositionItem> DecompositionItems { get; set; }
        public DateTime? DecompositionTime { get; set; }
        public DateTime? UndoTime { get; set; }
    }

    /// <summary>
    /// BOM分解预览
    /// </summary>
    public class BomDecompositionPreview
    {
        public Guid ProductionPlanId { get; set; }
        public string ProductionPlanName { get; set; }
        public Guid BomId { get; set; }
        public decimal PlanQuantity { get; set; }
        public List<DecompositionItem> DecompositionItems { get; set; }
        public int EstimatedOrders { get; set; }
        public bool CanDecompose { get; set; }
        public string CurrentStatus { get; set; }
    }

    /// <summary>
    /// 验证结果
    /// </summary>
    public class ValidationResult
    {
        public bool IsValid { get; set; }
        public string ErrorMessage { get; set; }
        public ProductionPlan ProductionPlan { get; set; }
    }

    /// <summary>
    /// BOM分解详细信息
    /// </summary>
    public class BomDecompositionDetail
    {
        public Guid ProductionPlanId { get; set; }
        public string ProductionPlanName { get; set; }
        public Guid BomId { get; set; }
        public decimal PlanQuantity { get; set; }
        public DateTime PlanStartTime { get; set; }
        public DateTime PlanEndTime { get; set; }
        public int Status { get; set; }
        public string StatusDescription { get; set; }
        public int BomTreeNodes { get; set; }
        public int TotalDecompositionItems { get; set; }
        public List<DecompositionItem> ProductItems { get; set; }
        public int ProductCount { get; set; }
        public List<DecompositionItem> MaterialItems { get; set; }
        public int MaterialCount { get; set; }
        public int WillGenerateOrders { get; set; }
        public List<ProductionOrder> ExistingOrders { get; set; }
        public int ExistingOrderCount { get; set; }
        public bool CanDecompose { get; set; }
        public bool IsDecomposed { get; set; }
        public DateTime AnalysisTime { get; set; }
    }
} 